<?php
// 应用公共文件
error_reporting(E_NOTICE);

/**
 * 将表情进行转义  用于存储的时候
 * @param  [type] $str [description]
 * @return [type]      [description]
 */
function emoji_encode($str){
    $strEncode = '';
    $length = mb_strlen($str,'utf-8');
    for ($i=0; $i < $length; $i++) {
        $_tmpStr = mb_substr($str,$i,1,'utf-8');
        if(strlen($_tmpStr) >= 4){
            $strEncode .= '[[EMOJI:'.rawurlencode($_tmpStr).']]';
        }else{
            $strEncode .= $_tmpStr;
        }
    }
    return $strEncode;
}

/**
 * 将表情进行反转义  用于读取的时候
 * @param  [type] $str [description]
 * @return [type]      [description]
 */
function emoji_decode($str){
    $strDecode = preg_replace_callback('|\[\[EMOJI:(.*?)\]\]|', function($matches){
        return rawurldecode($matches[1]);
    }, $str);
    return $strDecode;
}

/**
 * 根据时间戳比较，获取状态
 * @param  [type] $start_time 开始时间戳
 * @param  [type] $end_time   结束时间戳
 * @param  [type] $text   格式类型
 * @return [type]             [description]
 */
function getTimeStatus($start_time, $end_time, $type = 'text')
{
	if($type == 'text') {
		if(time() < $start_time && time() < $end_time) {
			$str = "<span style='color: #0a6aa1;'>未开始</em>";
		}else if(time() >= $start_time && time() < $end_time) {
			$str = "<span style='color: #19be6b;'>进行中</em>";
		}else {
			$str = "<span style='color: #ff0000;'>已结束</em>";
		}
	}else {
		if(time() < $start_time && time() < $end_time) {
			$str = 0;  //未开始
		}else if(time() >= $start_time && time() < $end_time) {
			$str = 1;  //进行中
		}else {
			$str = 2; //已结束
		}
	}
	return $str;
}

/**
 * 返回时间段的日期、时间戳
 * @param string $type  时间类型
 * @param array $map  ['pm'=>'-', 'n'=>1] pm:表示正或负， n:表示天数
 * @param boolean $slot true返回时间段，否当天时间
 * @return void
 */
function getTime($type = "", $map = ['pm'=>'-', 'n'=>1], $slot = false)
{
    switch ($type) {
        case 'day':  //昨天、明天、近七天、近一个月、近半年、近一年...
            $n = $map['n'] ? : 1;
            if($map['pm'] == '+') {
                $date = date("Y-m-d", strtotime("+{$n} day"));
                if($slot) {
                    $start_time = time();
                    $end_time = strtotime("+{$n} day");
                }else {
                    $start_time = strtotime($date);
                    $end_time = $start_time + + 60 * 60 * 24 - 1;
                }
            }else {
                $date = date("Y-m-d", strtotime("-{$n} day"));
                $start_time = strtotime($date);
                $end_time = $slot ? time() : ($start_time + 60 * 60 * 24 - 1);
            }
            $arr = [
                'start_time' => $start_time,
                'start_date' => date("Y-m-d H:i:s", $start_time),
                'end_time' => $end_time,
                'end_date' => date("Y-m-d H:i:s", $end_time),
            ];
            break;
        default: //今日
            $start_time = strtotime(date("Y-m-d", time()));
            $end_time = $start_time + 60 * 60 * 24 - 1;
            $arr = [
                'start_time' => $start_time,
                'start_date' => date("Y-m-d H:i:s", $start_time),
                'end_time' => $end_time,
                'end_date' => date("Y-m-d H:i:s", $end_time),
            ];
            break;
    }
    return $arr;
}

/**
 * 根据时间戳转年月日
 * @param $time 时间戳
 * @return string
 */
function time_tran($time)
{
    $t = time() - $time;
    if($t <= 0) return '刚刚';
    $f = [
    	'31536000' => '年',
        '2592000' => '个月',
        '604800' => '星期',
        '86400' => '天',
        '3600' => '小时',
        '60' => '分钟',
        '1' => '秒'
    ];
    foreach ($f as $k => $v) {
        if (0 != $c = floor($t / (int)$k)) {
            return $c . $v . '前';
        }
    }
}

/**
 * 时间 H:i:s 转 s
 * @User yaokai
 * @param $his
 * @return float|int
 */
function HisToS($his)
{
    $str = explode(':', $his);
    $len = count($str);
    if ($len == 3) {
        $time = $str[0] * 3600 + $str[1] * 60 + $str[2];
    } elseif ($len == 2) {
        $time = $str[0] * 60 + $str[1];
    } elseif ($len == 1) {
        $time = $str[0];
    } else {
        $time = 0;
    }
    return $time;
}

/**
 *  把秒数转换为时分秒(00:00:00)或分秒(00:00)的格式
 *  @param Int $times 时间，单位(秒)
 *  @param Int $type 1-时分秒 2-分秒
 *  @return String
 */
function secondToTime($times,$type = 1){
    if($type == 1){
        $result = '00:00:00';
        if ($times>0) {
            $hour = floor($times/3600);
            $minute = floor(($times-3600 * $hour)/60);
            $second = floor((($times-3600 * $hour) - 60 * $minute) % 60);
            $hour = $hour < 10 ? '0'.$hour : $hour;
            $minute = $minute < 10 ? '0'.$minute : $minute;
            $second = $second < 10 ? '0'.$second : $second;
            $result = $hour.':'.$minute.':'.$second;
        }
    }else{
        $result = '00:00';
        if ($times>0) {
            $hour = floor($times/3600);
            $minute = floor(($times-3600 * $hour)/60);
            $second = floor((($times-3600 * $hour) - 60 * $minute) % 60);
            $hour = $hour < 10 ? '0'.$hour : $hour;
            $minute = $hour*60 + $minute;
            $minute = $minute < 10 ? '0'.$minute : $minute;
            $second = $second < 10 ? '0'.$second : $second;
            $result = $minute.':'.$second;
        }
    }
    return $result;
}

/**
 * 获取指定年月日的开始时间戳和结束时间戳(本地时间戳非GMT时间戳)
 * [1] 指定年：获取指定年份第一天第一秒的时间戳和下一年第一天第一秒的时间戳
 * [2] 指定年月：获取指定年月第一天第一秒的时间戳和下一月第一天第一秒时间戳
 * [3] 指定年月日：获取指定年月日第一天第一秒的时间戳
 * @param  integer $year     [年份]
 * @param  integer $month    [月份]
 * @param  integer $day      [日期]
 * @return array('start' => '', 'end' => '')
 */
function getStartAndEndUnixTimestamp($year = 0, $month = 0, $day = 0)
{
    if(empty($year))
    {
        $year = date("Y");
    }

    $start_year = $year;
    $start_year_formated = str_pad(intval($start_year), 4, "0", STR_PAD_RIGHT);
    $end_year = $start_year + 1;
    $end_year_formated = str_pad(intval($end_year), 4, "0", STR_PAD_RIGHT);

    if(empty($month))
    {
        //只设置了年份
        $start_month_formated = '01';
        $end_month_formated = '01';
        $start_day_formated = '01';
        $end_day_formated = '01';
    }
    else
    {
        $month > 12 || $month < 1 ? $month = 1 : $month = $month;
        $start_month = $month;
        $start_month_formated = sprintf("%02d", intval($start_month));

        if(empty($day))
        {
            //只设置了年份和月份
            $end_month = $start_month + 1;

            if($end_month > 12)
            {
                $end_month = 1;
            }
            else
            {
                $end_year_formated = $start_year_formated;
            }
            $end_month_formated = sprintf("%02d", intval($end_month));
            $start_day_formated = '01';
            $end_day_formated = '01';
        }
        else
        {
            //设置了年份月份和日期
            $startTimestamp = strtotime($start_year_formated.'-'.$start_month_formated.'-'.sprintf("%02d", intval($day))." 00:00:00");
            $endTimestamp = $startTimestamp + 24 * 3600 - 1;
            return array('start' => $startTimestamp, 'end' => $endTimestamp);
        }
    }

    $startTimestamp = strtotime($start_year_formated.'-'.$start_month_formated.'-'.$start_day_formated." 00:00:00");
    $endTimestamp = strtotime($end_year_formated.'-'.$end_month_formated.'-'.$end_day_formated." 00:00:00") - 1;
    return array('start' => $startTimestamp, 'end' => $endTimestamp);
}

/**
 * 匿名处理
 * @param string $data   数据
 * @param string $type   类型
 * @param int    $start  开始显示位数，自定义填
 * @param int    $end    结束显示位数，自定义填
 * @param string $symbol 符号
 * @return [type]       [description]
 */
function anonymity($data, $type = "", $start = 1, $end = 0, $symbol = '*')
{
    if(!$data) return '';
    switch ($type) {
        case 'mobile':
            return substr_replace($data, '****', 3, 4);
            break;
        case 'name'://姓名加密
            if(preg_match("/[\x{4e00}-\x{9fa5}]+/u", $data)) {//判断是否包含中文字符
                //按照中文字符计算长度
                $len = mb_strlen($data, 'UTF-8');
                if($len >= 3){//三个字符或三个字符以上掐头取尾，中间用*代替
                    return mb_substr($data, 0, 1, 'UTF-8') . str_repeat($symbol, $len-2) . mb_substr($data, -1, 1, 'UTF-8');
                } elseif($len === 2) {//两个字符
                    return mb_substr($data, 0, 1, 'UTF-8') . $symbol;
                }
            } else {
                //按照英文字串计算长度
                $len = strlen($data);
                if($len >= 3) {//三个字符或三个字符以上掐头取尾，中间用*代替
                    return substr($data, 0, 1)  . str_repeat($symbol, $len-2) . substr($data, -1);
                } elseif($len === 2) {//两个字符
                    return substr($data, 0, 1) . $symbol;
                }
            }
            break;
        default://自定义加密
            $len = mb_strlen($data,'UTF-8') - $start - $end;
            if($len > 0){
                $str = str_repeat($symbol,$len);//替换字符数量
                if(preg_match("/[\x{4e00}-\x{9fa5}]+/u", $data)) {//含有中文
                    return mb_substr($data, 0, $start, 'UTF-8') . $str . mb_substr($data, $start + $len , $end, 'UTF-8');
                } else {
                    return substr_replace($data, $str, $start, $len);
                }
            } elseif($len == 0){
                return mb_substr($data, 0, 1, 'UTF-8') . str_repeat($symbol, mb_strlen($data,'UTF-8') - 1) . mb_substr($data, -1, 1, 'UTF-8');
            } else{
                return $data . $symbol;
            }
            break;
    }
}

/**
* 生成随机数
* $type: 1:纯数字  2： 纯小写字母 ，否则结合
* $length: 指定生成数量
*/
function rand_code($length, $type = ''){
    switch ($type) {
        case 1:
            $chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
            break;
        case 2:
            $chars = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
                        'i', 'j', 'k', 'l','m', 'n', 'o', 'p', 'q', 'r', 's',
                        't', 'u', 'v', 'w', 'x', 'y','z'];
            break;
        default:
            $chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',
                        'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L','M', 'N', 'O',
                        'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y','Z'];
            break;
    }
    $keys = array_rand($chars, $length);
    $str = '';
    for($i = 0; $i < $length; $i++){
        $str .= $chars[$keys[$i]];
    }
    return $str;
}

/**
 * 检查密码复杂度
 * @param $pwd 密码
 * @param int $pwdLen 密码长度，默认6位
 * @return array
 */
function checkPassword($pwd, $pwdLen = 6) {
    if ($pwd == null) {
        return ['code' => 500, 'msg' => '密码不能为空'];
    }
    $pwd = trim($pwd);
    if (preg_match('/[\x{4e00}-\x{9fa5}]/u', $pwd) > 0) {
        return ['code' => 500, 'msg' => '密码不能包含中文'];
    }
    if (strlen($pwd) < $pwdLen) {
        return ['code'=>500,'msg'=>'密码必须大于'.$pwdLen.'个字符'];
    }
    if (preg_match_all('/[0-9]/', $pwd, $o) < 1) {
        return ['code'=>500,'msg'=>'密码必须包含至少一个数字'];
    }
    if (preg_match_all('/[a-z]/', $pwd, $o) < 1) {
        return ['code'=>500,'msg'=>'密码必须包含至少一个小写字母'];
    }
    if (preg_match_all('/[A-Z]/', $pwd, $o) < 1) {
        return ['code'=>500,'msg'=>'密码必须包含至少一个大写字母'];
    }
    if (preg_match_all('/[!@#$%^&*]/', $pwd, $o) < 1) {
        return ['code'=>500,'msg'=>'密码必须包含至少一个特殊符号 !@#$%^&*'];
    }
    return ['code' => 200, 'msg' => '密码复杂度通过验证'];
}

/**
 * 默认返回1
 * @param  integer $val [description]
 * @return boolean      [description]
 */
function isShow($val = 1, $check = "")
{
	if($check && !isset($val)){
		$val = 0;  //默认选中否
	}else if(!isset($val)){
		$val = 1;
	}
	return $val;
}

/**
 * 二维数组根据某字段排序
 * @param  array   $data  二维数组
 * @param  string  $field 字段
 * @param  integer $type  排序  1:SORT_DESC 降序, 0:SORT_ASC 升序
 * @return [type]         [description]
 */
function arrSort($data = [], $field = "id", $type = 0)
{
	if(empty($data)) return $data;
	$sort = [
		'direction' => $type == 1 ? 'SORT_DESC' : 'SORT_ASC',
	    'field'     => $field,  //排序字段
	];
	$arr = [];
	foreach($data AS $k => $v){
	    foreach($v AS $key => $value){
	        $arr[$key][$k] = $value;
	    }
	}
	array_multisort($arr[$sort['field']], constant($sort['direction']), $data);
	return $data;
}


/**
 * 二维数组（二维只有一个字段）转一维数字键数组
 * @param $arr
 * @param $field
 * @return array
 */
function turnArr($data, $field = ''){
	if(empty($data)) return $data;
    $arr = [];
    foreach($data as $k => $v){
        if(empty($field) || count($v) == 1) {
            $arr[$k] = array_shift($v);
        }else {
            $arr[$k] = $v[$field];
        }
    }
    return $arr;
}

/**
 * 获取性别
 * @param integer $val
 * @return void
 */
function getSex($val = 0){
	switch ($val) {
		case 1:
			$str = "男";
			break;
		case 2:
			$str = "女";
			break;
		default:
			$str = "保密";
			break;
	}
	return $str;
}

/**
 * 小程序编辑器值替换
 * @param  [type] $detail [description]
 * @return [type]         [description]
 */
function xcx_detail($detail)
{
    return str_replace(['/uploads/ueditor','&nbsp;'], [request()->domain().'/uploads/ueditor','&ensp;'], htmlspecialchars_decode($detail));
}

function isTips($var = "")
{
    if(!$var) return "--";
    return $var;
}

/**
 * 把1000转换为1k，10000转换为1w
 * @param $num
 * @return mixed|string
 */
function convert($num)
{
    if ($num >= 100000)
    {
        $num = round($num / 10000) .'W+';
    }
    else if ($num >= 10000)
    {
        $num = round($num / 10000, 1) .'W+';
    }
    else if($num >= 1000)
    {
        $num = round($num / 1000, 1) . 'K+';
    }
    return $num;
}

/**
 * Guzzle请求 https://guzzle-cn.readthedocs.io/zh_CN/latest/
 * @param $url 请求地址
 * @param array $data 数据
 * @param string $method 请求方法
 * @param string $options 请求选项 [常用：GET=>query  POST=>form_params  POST=>json ]  //https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html
 * @param array $headers 请求头
 * @return array
 * @throws \GuzzleHttp\Exception\GuzzleException
 */
function guzzle_request($url, $data = [] , $method = "GET", $options = 'query' , $headers = [])
{
    try {
        $client = new \GuzzleHttp\Client(['http_error'=>false]);
//        array_unshift($headers,['content-type' => 'application/json;charset=utf-8']);
        $headers = array_merge(['content-type' => 'application/json;charset=utf-8'],$headers);

        $parameter = [$options => $data, 'headers' => $headers];

        $res = $client->request($method, $url, $parameter);

        return json_decode($res->getBody()->getContents(),true);

    } catch (\GuzzleHttp\Exception\RequestException $e) {
//            dd($e->getRequest());dd($e->getResponse());
        return false;
    }
}
